package vn.vfriends.mcms.admin.bean;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vn.vfriends.mcms.admin.model.Role;
import vn.vfriends.mcms.admin.model.User;
import vn.vfriends.mcms.admin.service.UserService;

/**
 *
 * @author tuan@vfriends.vn
 */
@Named
@SessionScoped
public class SecurityBean implements Serializable {

    private Logger logger = LoggerFactory.getLogger(SecurityBean.class);
    private String username;
    private String password;
    private User loggedUser;
    @Inject private UserService userService;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User getLoggedUser() {
        if(loggedUser == null) {
            FacesContext context = FacesContext.getCurrentInstance();
            HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
            HttpSession session = request.getSession();
            loggedUser = (User)session.getAttribute("LOGGED_USER");
        }
            
        return loggedUser;
    }
    
    public String loginAction() {
        FacesContext context = FacesContext.getCurrentInstance();
        String outcome = "";
        try {
            User user = this.userService.findUserByUsername(username);
            if(user == null || !user.getPassword().equals(DigestUtils.md5Hex(password))) {
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Đăng nhập không thành công", ""));
            } if(!user.isActivated()) {
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Người dùng chưa được kích hoạt", ""));
            } else {
                loggedUser = user;
                HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
                HttpSession session = request.getSession();
                session.setAttribute("LOGGED_USER", loggedUser);
                
                // Get roles of logged user
                session.setAttribute("LOGGED_USER_ROLES", user.getRoles());
                outcome = "home?faces-redirect=true";
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
        }
        return outcome;
    }
    
    public String logoutAction() {
        FacesContext context = FacesContext.getCurrentInstance();
        try{
            loggedUser = null;
            HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
            request.getSession().invalidate();
            return "/index?faces-redirect=true";
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
        }
        return "";
    }
    
    public boolean isUserInRole(Role.RoleCode code) {
        FacesContext context = FacesContext.getCurrentInstance();
        boolean returnVal = false;
        try {
            HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
            HttpSession session = request.getSession(false);
            List<Role> roles = (List<Role>) session.getAttribute("LOGGED_USER_ROLES");
            for (Role role : roles) {
                if (role.getCode().equals(code)) {
                    returnVal = true;
                    break;
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return returnVal;
    }
}
